<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
        "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <link href="../Styles/style.css" rel="stylesheet" type="text/css"/>


</head>

<body>
<div class="article-body">

    <div class="article-intro" id="content">

        <h1>Python3 模块</h1>
        <p>在前面的几个章节中我们脚本上是用 python 解释器来编程，如果你从 Python 解释器退出再进入，那么你定义的所有的方法和变量就都消失了。</p>
        <p>为此 Python 提供了一个办法，把这些定义存放在文件中，为一些脚本或者交互式的解释器实例使用，这个文件被称为模块。</p>
        <p>模块是一个包含所有你定义的函数和变量的文件，其后缀名是.py。模块可以被别的程序引入，以使用该模块中的函数等功能。这也是使用 python 标准库的方法。</p>
        <p>下面是一个使用 python 标准库中模块的例子。
        </p>
        <pre class="prettyprint prettyprinted" style=""><span class="com">#!/usr/bin/python3</span><span class="pln">
</span><span class="com"># 文件名: using_sys.py</span><span class="pln">

</span><span class="kwd">import</span><span class="pln"> sys

</span><span class="kwd">print</span><span class="pun">(</span><span class="str">'命令行参数如下:'</span><span
                class="pun">)</span><span class="pln">
</span><span class="kwd">for</span><span class="pln"> i </span><span class="kwd">in</span><span
                class="pln"> sys</span><span class="pun">.</span><span class="pln">argv</span><span class="pun">:</span><span
                class="pln">
   </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">i</span><span
                class="pun">)</span><span class="pln">

</span><span class="kwd">print</span><span class="pun">(</span><span class="str">'\n\nPython 路径为：'</span><span
                class="pun">,</span><span class="pln"> sys</span><span class="pun">.</span><span class="pln">path</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'\n'</span><span
                class="pun">)</span></pre>
        <p>执行结果如下所示：</p>
        <pre class="prettyprint prettyprinted" style=""><span class="pln">$ python using_sys</span><span
                class="pun">.</span><span class="pln">py </span><span class="pun">参数</span><span
                class="lit">1</span><span class="pln"> </span><span class="pun">参数</span><span class="lit">2</span><span
                class="pln">
</span><span class="pun">命令行参数如下:</span><span class="pln">
using_sys</span><span class="pun">.</span><span class="pln">py
</span><span class="pun">参数</span><span class="lit">1</span><span class="pln">
</span><span class="pun">参数</span><span class="lit">2</span><span class="pln">


</span><span class="typ">Python</span><span class="pln"> </span><span class="pun">路径为：</span><span
                class="pln"> </span><span class="pun">[</span><span class="str">'/root'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'/usr/lib/python3.4'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'/usr/lib/python3.4/plat-x86_64-linux-gnu'</span><span
                class="pun">,</span><span class="pln"> </span><span
                class="str">'/usr/lib/python3.4/lib-dynload'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'/usr/local/lib/python3.4/dist-packages'</span><span
                class="pun">,</span><span class="pln"> </span><span
                class="str">'/usr/lib/python3/dist-packages'</span><span class="pun">]</span><span class="pln">
</span></pre>
        <ul>
            <li>1、import sys 引入 python 标准库中的 sys.py 模块；这是引入某一模块的方法。</li>
            <li>
                2、sys.argv 是一个包含命令行参数的列表。
            </li>
            <li>
                3、sys.path 包含了一个 Python 解释器自动查找所需模块的路径的列表。
            </li>
        </ul>



        <h2>import 语句</h2>

        <p>想使用 Python 源文件，只需在另一个源文件里执行 import 语句，语法如下：</p>
        <pre class="prettyprint prettyprinted" style=""><span class="kwd">import</span><span class="pln"> module1</span><span
                class="pun">[,</span><span class="pln"> module2</span><span class="pun">[,...</span><span class="pln"> moduleN</span><span
                class="pun">]</span></pre>
        <p>
            当解释器遇到 import 语句，如果模块在当前的搜索路径就会被导入。
        </p>
        <p>搜索路径是一个解释器会先进行搜索的所有目录的列表。如想要导入模块 support，需要把命令放在脚本的顶端：</p>
        <p>support.py 文件代码为：</p>
        <pre class="prettyprint prettyprinted" style=""><span class="com">#!/usr/bin/python3</span><span class="pln">
</span><span class="com"># Filename: support.py</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> print_func</span><span class="pun">(</span><span
                class="pln"> par </span><span class="pun">):</span><span class="pln">
    </span><span class="kwd">print</span><span class="pln"> </span><span class="pun">(</span><span class="str">"Hello : "</span><span
                class="pun">,</span><span class="pln"> par</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">return</span></pre>
        <p>test.py 引入 support 模块：</p>
        <pre class="prettyprint prettyprinted" style=""><span class="com">#!/usr/bin/python3</span><span class="pln">
</span><span class="com"># Filename: test.py</span><span class="pln">

</span><span class="com"># 导入模块</span><span class="pln">
</span><span class="kwd">import</span><span class="pln"> support

</span><span class="com"># 现在可以调用模块里包含的函数了</span><span class="pln">
support</span><span class="pun">.</span><span class="pln">print_func</span><span class="pun">(</span><span class="str">"Runoob"</span><span
                class="pun">)</span></pre>
        <p>
            以上实例输出结果：</p>
        <pre class="prettyprint prettyprinted" style=""><span class="pln">$ python3 test</span><span
                class="pun">.</span><span class="pln">py
</span><span class="typ">Hello</span><span class="pln"> </span><span class="pun">:</span><span
                class="pln">  </span><span class="typ">Runoob</span></pre>
        <p>一个模块只会被导入一次，不管你执行了多少次import。这样可以防止导入模块被一遍又一遍地执行。</p>

        <p>当我们使用import语句的时候，Python解释器是怎样找到对应的文件的呢？</p>
        <p>这就涉及到Python的搜索路径，搜索路径是由一系列目录名组成的，Python解释器就依次从这些目录中去寻找所引入的模块。
        </p>
        <p>
            这看起来很像环境变量，事实上，也可以通过定义环境变量的方式来确定搜索路径。</p>
        <p>搜索路径是在Python编译或安装的时候确定的，安装新的库应该也会修改。搜索路径被存储在sys模块中的path变量，做一个简单的实验，在交互式解释器中，输入以下代码：
        </p>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">&gt;&gt;&gt;</span><span
                class="pln"> </span><span class="kwd">import</span><span class="pln"> sys
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> sys</span><span class="pun">.</span><span class="pln">path
</span><span class="pun">[</span><span class="str">''</span><span class="pun">,</span><span class="pln"> </span><span
                class="str">'/usr/lib/python3.4'</span><span class="pun">,</span><span class="pln"> </span><span
                class="str">'/usr/lib/python3.4/plat-x86_64-linux-gnu'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'/usr/lib/python3.4/lib-dynload'</span><span
                class="pun">,</span><span class="pln"> </span><span
                class="str">'/usr/local/lib/python3.4/dist-packages'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'/usr/lib/python3/dist-packages'</span><span
                class="pun">]</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> </span></pre>
        <p>sys.path 输出是一个列表，其中第一项是空串''，代表当前目录（若是从一个脚本中打印出来的话，可以更清楚地看出是哪个目录），亦即我们执行python解释器的目录（对于脚本的话就是运行的脚本所在的目录）。
        </p>
        <p>
            因此若像我一样在当前目录下存在与要引入模块同名的文件，就会把要引入的模块屏蔽掉。
        </p>

        <p>
            了解了搜索路径的概念，就可以在脚本中修改sys.path来引入一些不在搜索路径中的模块。
        </p>
        <p>
            现在，在解释器的当前目录或者 sys.path 中的一个目录里面来创建一个fibo.py的文件，代码如下：</p>
        <pre class="prettyprint prettyprinted" style=""><span class="com"># 斐波那契(fibonacci)数列模块</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> fib</span><span class="pun">(</span><span
                class="pln">n</span><span class="pun">):</span><span class="pln">    </span><span class="com"># 定义到 n 的斐波那契数列</span><span
                class="pln">
    a</span><span class="pun">,</span><span class="pln"> b </span><span class="pun">=</span><span
                class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span
                class="lit">1</span><span class="pln">
    </span><span class="kwd">while</span><span class="pln"> b </span><span class="pun">&lt;</span><span
                class="pln"> n</span><span class="pun">:</span><span class="pln">
        </span><span class="kwd">print</span><span class="pun">(</span><span class="pln">b</span><span
                class="pun">,</span><span class="pln"> </span><span class="kwd">end</span><span
                class="pun">=</span><span class="str">' '</span><span class="pun">)</span><span class="pln">
        a</span><span class="pun">,</span><span class="pln"> b </span><span class="pun">=</span><span
                class="pln"> b</span><span class="pun">,</span><span class="pln"> a</span><span
                class="pun">+</span><span class="pln">b
    </span><span class="kwd">print</span><span class="pun">()</span><span class="pln">

</span><span class="kwd">def</span><span class="pln"> fib2</span><span class="pun">(</span><span
                class="pln">n</span><span class="pun">):</span><span class="pln"> </span><span class="com"># 返回到 n 的斐波那契数列</span><span
                class="pln">
    result </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[]</span><span class="pln">
    a</span><span class="pun">,</span><span class="pln"> b </span><span class="pun">=</span><span
                class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> </span><span
                class="lit">1</span><span class="pln">
    </span><span class="kwd">while</span><span class="pln"> b </span><span class="pun">&lt;</span><span
                class="pln"> n</span><span class="pun">:</span><span class="pln">
        result</span><span class="pun">.</span><span class="pln">append</span><span class="pun">(</span><span
                class="pln">b</span><span class="pun">)</span><span class="pln">
        a</span><span class="pun">,</span><span class="pln"> b </span><span class="pun">=</span><span
                class="pln"> b</span><span class="pun">,</span><span class="pln"> a</span><span
                class="pun">+</span><span class="pln">b
    </span><span class="kwd">return</span><span class="pln"> result</span></pre>
        <p>然后进入Python解释器，使用下面的命令导入这个模块：</p>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">&gt;&gt;&gt;</span><span
                class="pln"> </span><span class="kwd">import</span><span class="pln"> fibo</span></pre>
        <p>这样做并没有把直接定义在fibo中的函数名称写入到当前符号表里，只是把模块fibo的名字写到了那里。
        </p>
        <p>
            可以使用模块名称来访问函数：
        </p>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">&gt;&gt;&gt;</span><span
                class="pln"> fibo</span><span class="pun">.</span><span class="pln">fib</span><span class="pun">(</span><span
                class="lit">1000</span><span class="pun">)</span><span class="pln">
</span><span class="lit">1</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span
                class="lit">2</span><span class="pln"> </span><span class="lit">3</span><span class="pln"> </span><span
                class="lit">5</span><span class="pln"> </span><span class="lit">8</span><span class="pln"> </span><span
                class="lit">13</span><span class="pln"> </span><span class="lit">21</span><span
                class="pln"> </span><span class="lit">34</span><span class="pln"> </span><span
                class="lit">55</span><span class="pln"> </span><span class="lit">89</span><span
                class="pln"> </span><span class="lit">144</span><span class="pln"> </span><span
                class="lit">233</span><span class="pln"> </span><span class="lit">377</span><span
                class="pln"> </span><span class="lit">610</span><span class="pln"> </span><span
                class="lit">987</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> fibo</span><span class="pun">.</span><span class="pln">fib2</span><span
                class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln">
</span><span class="pun">[</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span
                class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span
                class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">,</span><span
                class="pln"> </span><span class="lit">5</span><span class="pun">,</span><span class="pln"> </span><span
                class="lit">8</span><span class="pun">,</span><span class="pln"> </span><span class="lit">13</span><span
                class="pun">,</span><span class="pln"> </span><span class="lit">21</span><span class="pun">,</span><span
                class="pln"> </span><span class="lit">34</span><span class="pun">,</span><span class="pln"> </span><span
                class="lit">55</span><span class="pun">,</span><span class="pln"> </span><span
                class="lit">89</span><span class="pun">]</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> fibo</span><span class="pun">.</span><span class="pln">__name__
</span><span class="str">'fibo'</span></pre>
        <p>如果你打算经常使用一个函数，你可以把它赋给一个本地的名称：</p>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">&gt;&gt;&gt;</span><span
                class="pln"> fib </span><span class="pun">=</span><span class="pln"> fibo</span><span
                class="pun">.</span><span class="pln">fib
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> fib</span><span class="pun">(</span><span
                class="lit">500</span><span class="pun">)</span><span class="pln">
</span><span class="lit">1</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span
                class="lit">2</span><span class="pln"> </span><span class="lit">3</span><span class="pln"> </span><span
                class="lit">5</span><span class="pln"> </span><span class="lit">8</span><span class="pln"> </span><span
                class="lit">13</span><span class="pln"> </span><span class="lit">21</span><span
                class="pln"> </span><span class="lit">34</span><span class="pln"> </span><span
                class="lit">55</span><span class="pln"> </span><span class="lit">89</span><span
                class="pln"> </span><span class="lit">144</span><span class="pln"> </span><span
                class="lit">233</span><span class="pln"> </span><span class="lit">377</span></pre>


        <br>

        <h2>
            from…import 语句</h2>

        <p>Python的from语句让你从模块中导入一个指定的部分到当前命名空间中，语法如下：</p>
        <pre class="prettyprint prettyprinted" style=""><span class="kwd">from</span><span
                class="pln"> modname </span><span class="kwd">import</span><span class="pln"> name1</span><span
                class="pun">[,</span><span class="pln"> name2</span><span class="pun">[,</span><span
                class="pln"> </span><span class="pun">...</span><span class="pln"> nameN</span><span
                class="pun">]]</span></pre>
        <p>例如，要导入模块 fibo 的 fib 函数，使用如下语句：</p>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">&gt;&gt;&gt;</span><span
                class="pln"> </span><span class="kwd">from</span><span class="pln"> fibo </span><span
                class="kwd">import</span><span class="pln"> fib</span><span class="pun">,</span><span class="pln"> fib2
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> fib</span><span class="pun">(</span><span
                class="lit">500</span><span class="pun">)</span><span class="pln">
</span><span class="lit">1</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span
                class="lit">2</span><span class="pln"> </span><span class="lit">3</span><span class="pln"> </span><span
                class="lit">5</span><span class="pln"> </span><span class="lit">8</span><span class="pln"> </span><span
                class="lit">13</span><span class="pln"> </span><span class="lit">21</span><span
                class="pln"> </span><span class="lit">34</span><span class="pln"> </span><span
                class="lit">55</span><span class="pln"> </span><span class="lit">89</span><span
                class="pln"> </span><span class="lit">144</span><span class="pln"> </span><span
                class="lit">233</span><span class="pln"> </span><span class="lit">377</span></pre>
        <p>这个声明不会把整个fibo模块导入到当前的命名空间中，它只会将fibo里的fib函数引入进来。</p>

        <br>

        <h2>From…import* 语句</h2>
        <p>
            把一个模块的所有内容全都导入到当前的命名空间也是可行的，只需使用如下声明：
        </p>
        <pre class="prettyprint prettyprinted" style=""><span class="kwd">from</span><span
                class="pln"> modname </span><span class="kwd">import</span><span class="pln"> </span><span
                class="pun">*</span></pre>
        <p>这提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多地使用。
        </p>



        <h2>深入模块</h2>
        <p>模块除了方法定义，还可以包括可执行的代码。这些代码一般用来初始化这个模块。这些代码只有在第一次被导入时才会被执行。</p>
        <p>每个模块有各自独立的符号表，在模块内部为所有的函数当作全局符号表来使用。

        </p>
        <p>所以，模块的作者可以放心大胆的在模块内部使用这些全局变量，而不用担心把其他用户的全局变量搞花。
        </p>
        <p>从另一个方面，当你确实知道你在做什么的话，你也可以通过 modname.itemname 这样的表示法来访问模块内的函数。
        </p>
        <p>模块是可以导入其他模块的。在一个模块（或者脚本，或者其他地方）的最前面使用 import 来导入一个模块，当然这只是一个惯例，而不是强制的。被导入的模块的名称将被放入当前操作的模块的符号表中。
        </p>
        <p>还有一种导入的方法，可以使用 import 直接把模块内（函数，变量的）名称导入到当前操作模块。比如:</p>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">&gt;&gt;&gt;</span><span
                class="pln"> </span><span class="kwd">from</span><span class="pln"> fibo </span><span
                class="kwd">import</span><span class="pln"> fib</span><span class="pun">,</span><span class="pln"> fib2
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> fib</span><span class="pun">(</span><span
                class="lit">500</span><span class="pun">)</span><span class="pln">
</span><span class="lit">1</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span
                class="lit">2</span><span class="pln"> </span><span class="lit">3</span><span class="pln"> </span><span
                class="lit">5</span><span class="pln"> </span><span class="lit">8</span><span class="pln"> </span><span
                class="lit">13</span><span class="pln"> </span><span class="lit">21</span><span
                class="pln"> </span><span class="lit">34</span><span class="pln"> </span><span
                class="lit">55</span><span class="pln"> </span><span class="lit">89</span><span
                class="pln"> </span><span class="lit">144</span><span class="pln"> </span><span
                class="lit">233</span><span class="pln"> </span><span class="lit">377</span></pre>
        <p>这种导入的方法不会把被导入的模块的名称放在当前的字符表中（所以在这个例子里面，fibo 这个名称是没有定义的）。
        </p>
        <p>这还有一种方法，可以一次性的把模块中的所有（函数，变量）名称都导入到当前模块的字符表:
        </p>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">&gt;&gt;&gt;</span><span
                class="pln"> </span><span class="kwd">from</span><span class="pln"> fibo </span><span
                class="kwd">import</span><span class="pln"> </span><span class="pun">*</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> fib</span><span class="pun">(</span><span
                class="lit">500</span><span class="pun">)</span><span class="pln">
</span><span class="lit">1</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span
                class="lit">2</span><span class="pln"> </span><span class="lit">3</span><span class="pln"> </span><span
                class="lit">5</span><span class="pln"> </span><span class="lit">8</span><span class="pln"> </span><span
                class="lit">13</span><span class="pln"> </span><span class="lit">21</span><span
                class="pln"> </span><span class="lit">34</span><span class="pln"> </span><span
                class="lit">55</span><span class="pln"> </span><span class="lit">89</span><span
                class="pln"> </span><span class="lit">144</span><span class="pln"> </span><span
                class="lit">233</span><span class="pln"> </span><span class="lit">377</span></pre>
        <p>这将把所有的名字都导入进来，但是那些由单一下划线（_）开头的名字不在此例。大多数情况， Python程序员不使用这种方法，因为引入的其它来源的命名，很可能覆盖了已有的定义。
        </p>


        <h2>__name__属性</h2>
        <p>
            一个模块被另一个程序第一次引入时，其主程序将运行。如果我们想在模块被引入时，模块中的某一程序块不执行，我们可以用__name__属性来使该程序块仅在该模块自身运行时执行。
        </p>
        <pre class="prettyprint prettyprinted" style=""><span class="com">#!/usr/bin/python3</span><span class="pln">
</span><span class="com"># Filename: using_name.py</span><span class="pln">

</span><span class="kwd">if</span><span class="pln"> __name__ </span><span class="pun">==</span><span
                class="pln"> </span><span class="str">'__main__'</span><span class="pun">:</span><span class="pln">
   </span><span class="kwd">print</span><span class="pun">(</span><span class="str">'程序自身在运行'</span><span
                class="pun">)</span><span class="pln">
</span><span class="kwd">else</span><span class="pun">:</span><span class="pln">
   </span><span class="kwd">print</span><span class="pun">(</span><span class="str">'我来自另一模块'</span><span
                class="pun">)</span></pre>
        <p>
            运行输出如下：
        </p>
        <pre class="prettyprint prettyprinted" style=""><span class="pln">$ python using_name</span><span
                class="pun">.</span><span class="pln">py
</span><span class="pun">程序自身在运行</span></pre>

        <pre class="prettyprint prettyprinted" style=""><span class="pln">$ python
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> </span><span class="kwd">import</span><span class="pln"> using_name
</span><span class="pun">我来自另一模块</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span></pre>
        <p><b>
            说明：</b>
            每个模块都有一个__name__属性，当其值是'__main__'时，表明该模块自身在运行，否则是被引入。</p>

        <h2>dir() 函数</h2>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">内置的函数</span><span class="pln"> dir</span><span
                class="pun">()</span><span class="pln"> </span><span
                class="pun">可以找到模块内定义的所有名称。以一个字符串列表的形式返回:</span><span class="pln">
</span><span class="pun">&lt;/</span><span class="pln">p</span><span class="pun">&gt;</span><span class="pln">
</span><span class="str">&lt;pre&gt;</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> </span><span class="kwd">import</span><span class="pln"> fibo</span><span
                class="pun">,</span><span class="pln"> sys
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> dir</span><span class="pun">(</span><span class="pln">fibo</span><span
                class="pun">)</span><span class="pln">
</span><span class="pun">[</span><span class="str">'__name__'</span><span class="pun">,</span><span class="pln"> </span><span
                class="str">'fib'</span><span class="pun">,</span><span class="pln"> </span><span
                class="str">'fib2'</span><span class="pun">]</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> dir</span><span class="pun">(</span><span
                class="pln">sys</span><span class="pun">)</span><span class="pln">
</span><span class="pun">[</span><span class="str">'__displayhook__'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'__doc__'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'__excepthook__'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'__loader__'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'__name__'</span><span class="pun">,</span><span class="pln">
 </span><span class="str">'__package__'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'__stderr__'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'__stdin__'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'__stdout__'</span><span
                class="pun">,</span><span class="pln">
 </span><span class="str">'_clear_type_cache'</span><span class="pun">,</span><span class="pln"> </span><span
                class="str">'_current_frames'</span><span class="pun">,</span><span class="pln"> </span><span
                class="str">'_debugmallocstats'</span><span class="pun">,</span><span class="pln"> </span><span
                class="str">'_getframe'</span><span class="pun">,</span><span class="pln">
 </span><span class="str">'_home'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'_mercurial'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'_xoptions'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'abiflags'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'api_version'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'argv'</span><span
                class="pun">,</span><span class="pln">
 </span><span class="str">'base_exec_prefix'</span><span class="pun">,</span><span class="pln"> </span><span
                class="str">'base_prefix'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'builtin_module_names'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'byteorder'</span><span
                class="pun">,</span><span class="pln">
 </span><span class="str">'call_tracing'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'callstats'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'copyright'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'displayhook'</span><span
                class="pun">,</span><span class="pln">
 </span><span class="str">'dont_write_bytecode'</span><span class="pun">,</span><span class="pln"> </span><span
                class="str">'exc_info'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'excepthook'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'exec_prefix'</span><span
                class="pun">,</span><span class="pln">
 </span><span class="str">'executable'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'exit'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'flags'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'float_info'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'float_repr_style'</span><span class="pun">,</span><span
                class="pln">
 </span><span class="str">'getcheckinterval'</span><span class="pun">,</span><span class="pln"> </span><span
                class="str">'getdefaultencoding'</span><span class="pun">,</span><span class="pln"> </span><span
                class="str">'getdlopenflags'</span><span class="pun">,</span><span class="pln">
 </span><span class="str">'getfilesystemencoding'</span><span class="pun">,</span><span class="pln"> </span><span
                class="str">'getobjects'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'getprofile'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'getrecursionlimit'</span><span
                class="pun">,</span><span class="pln">
 </span><span class="str">'getrefcount'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'getsizeof'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'getswitchinterval'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'gettotalrefcount'</span><span
                class="pun">,</span><span class="pln">
 </span><span class="str">'gettrace'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'hash_info'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'hexversion'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'implementation'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'int_info'</span><span
                class="pun">,</span><span class="pln">
 </span><span class="str">'intern'</span><span class="pun">,</span><span class="pln"> </span><span
                class="str">'maxsize'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'maxunicode'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'meta_path'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'modules'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'path'</span><span
                class="pun">,</span><span class="pln">
 </span><span class="str">'path_hooks'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'path_importer_cache'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'platform'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'prefix'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'ps1'</span><span
                class="pun">,</span><span class="pln">
 </span><span class="str">'setcheckinterval'</span><span class="pun">,</span><span class="pln"> </span><span
                class="str">'setdlopenflags'</span><span class="pun">,</span><span class="pln"> </span><span
                class="str">'setprofile'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'setrecursionlimit'</span><span
                class="pun">,</span><span class="pln">
 </span><span class="str">'setswitchinterval'</span><span class="pun">,</span><span class="pln"> </span><span
                class="str">'settrace'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'stderr'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'stdin'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'stdout'</span><span class="pun">,</span><span class="pln">
 </span><span class="str">'thread_info'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'version'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'version_info'</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">'warnoptions'</span><span
                class="pun">]</span></pre>
        <p>如果没有给定参数，那么 dir() 函数会罗列出当前定义的所有名称:</p>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">&gt;&gt;&gt;</span><span
                class="pln"> a </span><span class="pun">=</span><span class="pln"> </span><span
                class="pun">[</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span
                class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span
                class="pun">,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">,</span><span
                class="pln"> </span><span class="lit">5</span><span class="pun">]</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> </span><span class="kwd">import</span><span class="pln"> fibo
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> fib </span><span class="pun">=</span><span class="pln"> fibo</span><span
                class="pun">.</span><span class="pln">fib
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> dir</span><span class="pun">()</span><span
                class="pln"> </span><span class="com"># 得到一个当前模块中定义的属性列表</span><span class="pln">
</span><span class="pun">[</span><span class="str">'__builtins__'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'__name__'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'a'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'fib'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'fibo'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'sys'</span><span class="pun">]</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> a </span><span class="pun">=</span><span
                class="pln"> </span><span class="lit">5</span><span class="pln"> </span><span
                class="com"># 建立一个新的变量 'a'</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> dir</span><span class="pun">()</span><span class="pln">
</span><span class="pun">[</span><span class="str">'__builtins__'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'__doc__'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'__name__'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'a'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'sys'</span><span class="pun">]</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> </span><span class="kwd">del</span><span
                class="pln"> a </span><span class="com"># 删除变量名a</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> dir</span><span class="pun">()</span><span class="pln">
</span><span class="pun">[</span><span class="str">'__builtins__'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'__doc__'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'__name__'</span><span class="pun">,</span><span
                class="pln"> </span><span class="str">'sys'</span><span class="pun">]</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span></pre>

        <h2>标准模块
        </h2>
        <p>
            Python 本身带着一些标准的模块库，在 Python 库参考文档中将会介绍到（就是后面的"库参考文档"）。</p>
        <p>有些模块直接被构建在解析器里，这些虽然不是一些语言内置的功能，但是他却能很高效的使用，甚至是系统级调用也没问题。</p>
        <p>这些组件会根据不同的操作系统进行不同形式的配置，比如 winreg 这个模块就只会提供给 Windows 系统。</p>
        <p>应该注意到这有一个特别的模块 sys ，它内置在每一个 Python 解析器中。变量 sys.ps1 和 sys.ps2 定义了主提示符和副提示符所对应的字符串:
        </p>
        <pre class="prettyprint prettyprinted" style=""><span class="pun">&gt;&gt;&gt;</span><span
                class="pln"> </span><span class="kwd">import</span><span class="pln"> sys
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> sys</span><span class="pun">.</span><span class="pln">ps1
</span><span class="str">'&gt;&gt;&gt; '</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> sys</span><span class="pun">.</span><span class="pln">ps2
</span><span class="str">'... '</span><span class="pln">
</span><span class="pun">&gt;&gt;&gt;</span><span class="pln"> sys</span><span class="pun">.</span><span
                class="pln">ps1 </span><span class="pun">=</span><span class="pln"> </span><span
                class="str">'C&gt; '</span><span class="pln">
C</span><span class="pun">&gt;</span><span class="pln"> </span><span class="kwd">print</span><span
                class="pun">(</span><span class="str">'Yuck!'</span><span class="pun">)</span><span class="pln">
</span><span class="typ">Yuck</span><span class="pun">!</span><span class="pln">
C</span><span class="pun">&gt;</span></pre>

        <h2>包</h2>
        <p>
            包是一种管理 Python 模块命名空间的形式，采用"点模块名称"。</p>
        <p>
            比如一个模块的名称是 A.B， 那么他表示一个包 A中的子模块 B 。</p>
        <p>就好像使用模块的时候，你不用担心不同模块之间的全局变量相互影响一样，采用点模块名称这种形式也不用担心不同库之间的模块重名的情况。
        </p>
        <p>这样不同的作者都可以提供 NumPy 模块，或者是 Python 图形库。
        </p>
        <p>不妨假设你想设计一套统一处理声音文件和数据的模块（或者称之为一个"包"）。</p>
        <p>现存很多种不同的音频文件格式（基本上都是通过后缀名区分的，例如： .wav，:file:.aiff，:file:.au，），所以你需要有一组不断增加的模块，用来在不同的格式之间转换。</p>
        <p>
            并且针对这些音频数据，还有很多不同的操作（比如混音，添加回声，增加均衡器功能，创建人造立体声效果），所以你还需要一组怎么也写不完的模块来处理这些操作。</p>
        <p>
            这里给出了一种可能的包结构（在分层的文件系统中）:

        </p>
        <pre class="prettyprint prettyprinted" style=""><span class="pln">sound</span><span class="pun">/</span><span
                class="pln">                          </span><span class="pun">顶层包</span><span class="pln">
      __init__</span><span class="pun">.</span><span class="pln">py               </span><span
                class="pun">初始化</span><span class="pln"> sound </span><span class="pun">包</span><span class="pln">
      formats</span><span class="pun">/</span><span class="pln">                  </span><span
                class="pun">文件格式转换子包</span><span class="pln">
              __init__</span><span class="pun">.</span><span class="pln">py
              wavread</span><span class="pun">.</span><span class="pln">py
              wavwrite</span><span class="pun">.</span><span class="pln">py
              aiffread</span><span class="pun">.</span><span class="pln">py
              aiffwrite</span><span class="pun">.</span><span class="pln">py
              auread</span><span class="pun">.</span><span class="pln">py
              auwrite</span><span class="pun">.</span><span class="pln">py
              </span><span class="pun">...</span><span class="pln">
      effects</span><span class="pun">/</span><span class="pln">                  </span><span class="pun">声音效果子包</span><span
                class="pln">
              __init__</span><span class="pun">.</span><span class="pln">py
              echo</span><span class="pun">.</span><span class="pln">py
              surround</span><span class="pun">.</span><span class="pln">py
              reverse</span><span class="pun">.</span><span class="pln">py
              </span><span class="pun">...</span><span class="pln">
      filters</span><span class="pun">/</span><span class="pln">                  filters </span><span
                class="pun">子包</span><span class="pln">
              __init__</span><span class="pun">.</span><span class="pln">py
              equalizer</span><span class="pun">.</span><span class="pln">py
              vocoder</span><span class="pun">.</span><span class="pln">py
              karaoke</span><span class="pun">.</span><span class="pln">py
              </span><span class="pun">...</span></pre>
        <p>
            在导入一个包的时候，Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。
        </p>
        <p>
            目录只有包含一个叫做 __init__.py 的文件才会被认作是一个包，主要是为了避免一些滥俗的名字（比如叫做 string）不小心的影响搜索路径中的有效模块。</p>
        <p>
            最简单的情况，放一个空的 :file:__init__.py就可以了。当然这个文件中也可以包含一些初始化代码或者为（将在后面介绍的） __all__变量赋值。
        </p>
        <p>
            用户可以每次只导入一个包里面的特定模块，比如: </p>
        <pre class="prettyprint prettyprinted" style=""><span class="kwd">import</span><span
                class="pln"> sound</span><span class="pun">.</span><span class="pln">effects</span><span
                class="pun">.</span><span class="pln">echo</span></pre>
        <p>
            这将会导入子模块:sound.effects.echo。 他必须使用全名去访问: </p>
        <pre class="prettyprint prettyprinted" style=""><span class="pln">sound</span><span class="pun">.</span><span
                class="pln">effects</span><span class="pun">.</span><span class="pln">echo</span><span
                class="pun">.</span><span class="pln">echofilter</span><span class="pun">(</span><span
                class="pln">input</span><span class="pun">,</span><span class="pln"> output</span><span
                class="pun">,</span><span class="pln"> delay</span><span class="pun">=</span><span
                class="lit">0.7</span><span class="pun">,</span><span class="pln"> atten</span><span
                class="pun">=</span><span class="lit">4</span><span class="pun">)</span></pre>
        <p>
            还有一种导入子模块的方法是: </p>
        <pre class="prettyprint prettyprinted" style=""><span class="kwd">from</span><span
                class="pln"> sound</span><span class="pun">.</span><span class="pln">effects </span><span class="kwd">import</span><span
                class="pln"> echo</span></pre>
        <p>
            这同样会导入子模块: echo，并且他不需要那些冗长的前缀，所以他可以这样使用: </p>
        <pre class="prettyprint prettyprinted" style=""><span class="pln">echo</span><span class="pun">.</span><span
                class="pln">echofilter</span><span class="pun">(</span><span class="pln">input</span><span
                class="pun">,</span><span class="pln"> output</span><span class="pun">,</span><span
                class="pln"> delay</span><span class="pun">=</span><span class="lit">0.7</span><span
                class="pun">,</span><span class="pln"> atten</span><span class="pun">=</span><span
                class="lit">4</span><span class="pun">)</span></pre>
        <p>
            还有一种变化就是直接导入一个函数或者变量: </p>
        <pre class="prettyprint prettyprinted" style=""><span class="kwd">from</span><span
                class="pln"> sound</span><span class="pun">.</span><span class="pln">effects</span><span
                class="pun">.</span><span class="pln">echo </span><span class="kwd">import</span><span class="pln"> echofilter</span></pre>
        <p>
            同样的，这种方法会导入子模块: echo，并且可以直接使用他的 echofilter() 函数:
        </p>
        <p>
            echofilter(input, output, delay=0.7, atten=4)

        </p>
        <p>
            注意当使用from package import item这种形式的时候，对应的item既可以是包里面的子模块（子包），或者包里面定义的其他名称，比如函数，类或者变量。</p>
        <p>
            import语法会首先把item当作一个包定义的名称，如果没找到，再试图按照一个模块去导入。如果还没找到，恭喜，一个:exc:ImportError 异常被抛出了。
        </p>
        <p>
            反之，如果使用形如import item.subitem.subsubitem这种导入形式，除了最后一项，都必须是包，而最后一项则可以是模块或者是包，但是不可以是类，函数或者变量的名字。
        </p>

        <h2>
            从一个包中导入* </h2>
        <p>
            设想一下，如果我们使用 from sound.effects import *会发生什么？
        </p>
        <p>Python 会进入文件系统，找到这个包里面所有的子模块，一个一个的把它们都导入进来。</p>
        <p>
            但是很不幸，这个方法在 Windows平台上工作的就不是非常好，因为Windows是一个大小写不区分的系统。</p>
        <p>在这类平台上，没有人敢担保一个叫做 ECHO.py 的文件导入为模块 echo 还是 Echo 甚至 ECHO。</p>
        <p>
            （例如，Windows 95就很讨厌的把每一个文件的首字母大写显示）而且 DOS 的 8+3 命名规则对长模块名称的处理会把问题搞得更纠结。
        </p>
        <p>
            为了解决这个问题，只能烦劳包作者提供一个精确的包的索引了。</p>
        <p>
            导入语句遵循如下规则：如果包定义文件 __init__.py 存在一个叫做 __all__ 的列表变量，那么在使用 from package import * 的时候就把这个列表中的所有名字作为包内容导入。</p>
        <p>

        </p>
        <p>作为包的作者，可别忘了在更新包之后保证 __all__
            也更新了啊。你说我就不这么做，我就不使用导入*这种用法，好吧，没问题，谁让你是老板呢。这里有一个例子，在:file:sounds/effects/__init__.py中包含如下代码:</p>
        <p>
        </p>
        <pre class="prettyprint prettyprinted" style=""><span class="pln">__all__ </span><span class="pun">=</span><span
                class="pln"> </span><span class="pun">[</span><span class="str">"echo"</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">"surround"</span><span
                class="pun">,</span><span class="pln"> </span><span class="str">"reverse"</span><span
                class="pun">]</span></pre>

        <p>
            这表示当你使用from sound.effects import *这种用法时，你只会导入包里面这三个子模块。 </p>
        <p>

            如果 <strong>__all__</strong> 真的没有定义，那么使用<strong>from sound.effects import *</strong>这种语法的时候，就不会导入包
            sound.effects 里的任何子模块。他只是把包sound.effects和它里面定义的所有内容导入进来（可能运行__init__.py里定义的初始化代码）。 </p>
        <p>
            这会把 __init__.py 里面定义的所有名字导入进来。并且他不会破坏掉我们在这句话之前导入的所有明确指定的模块。看下这部分代码: </p>
        <pre class="prettyprint prettyprinted" style=""><span class="kwd">import</span><span
                class="pln"> sound</span><span class="pun">.</span><span class="pln">effects</span><span
                class="pun">.</span><span class="pln">echo
</span><span class="kwd">import</span><span class="pln"> sound</span><span class="pun">.</span><span
                class="pln">effects</span><span class="pun">.</span><span class="pln">surround
</span><span class="kwd">from</span><span class="pln"> sound</span><span class="pun">.</span><span
                class="pln">effects </span><span class="kwd">import</span><span class="pln"> </span><span
                class="pun">*</span></pre>
        <p>
            这个例子中，在执行from...import前，包sound.effects中的echo和surround模块都被导入到当前的命名空间中了。（当然如果定义了__all__就更没问题了）
        </p>
        <p>
            通常我们并不主张使用*这种方法来导入模块，因为这种方法经常会导致代码的可读性降低。不过这样倒的确是可以省去不少敲键的功夫，而且一些模块都设计成了只能通过特定的方法导入。</p>
        <p>

            记住，使用from Package import specific_submodule这种方法永远不会有错。事实上，这也是推荐的方法。除非是你要导入的子模块有可能和其他包的子模块重名。</p>
        <p>
            如果在结构中包是一个子包（比如这个例子中对于包sound来说），而你又想导入兄弟包（同级别的包）你就得使用导入绝对的路径来导入。比如，如果模块sound.filters.vocoder
            要使用包sound.effects中的模块echo，你就要写成 from sound.effects import echo。</p>
        <pre class="prettyprint prettyprinted" style=""><span class="kwd">from</span><span class="pln"> </span><span
                class="pun">.</span><span class="pln"> </span><span class="kwd">import</span><span class="pln"> echo
</span><span class="kwd">from</span><span class="pln"> </span><span class="pun">..</span><span class="pln"> </span><span
                class="kwd">import</span><span class="pln"> formats
</span><span class="kwd">from</span><span class="pln"> </span><span class="pun">..</span><span
                class="pln">filters </span><span class="kwd">import</span><span class="pln"> equalizer</span></pre>
        <p>
            无论是隐式的还是显式的相对导入都是从当前模块开始的。主模块的名字永远是"__main__"，一个Python应用程序的主模块，应当总是使用绝对路径引用。
        </p>
        <p>
            包还提供一个额外的属性__path__。这是一个目录列表，里面每一个包含的目录都有为这个包服务的__init__.py，你得在其他__init__.py被执行前定义哦。可以修改这个变量，用来影响包含在包里面的模块和子包。
        </p>
        <p>
            这个功能并不常用，一般用来扩展包里面的模块。 </p>

    </div>
</div>
</body>
</html>
